﻿package com.jxl.dnd.abilities
{
	import com.jxl.dnd.Modifier;
	import com.jxl.dnd.events.DnDEvent;
	
	import flash.events.EventDispatcher;
	
	import mx.collections.ArrayCollection;
	
	[Event(name="abilityScoreChanged", type="com.jxl.dnd.events.DnDEvent")]
	public class AbilityScores extends EventDispatcher
	{
		public static const STRENGTH:uint 				= 0;
		public static const DEXTERITY:uint 				= 1;
		public static const CONSTITUTION:uint 			= 2;
		public static const INTELLIGENCE:uint 			= 3;
		public static const WISDOM:uint 				= 4;
		public static const CHARISMA:uint 				= 5;
		
		[Bindable("abilityScoreChanged")]
		public function get strength():int { return str; }
		public function set strength(val:int):void
		{
			str = val;
			dispatchChangeEvent(STRENGTH);
		}
		
		[Bindable("abilityScoreChanged")]
		public function get dexterity():int { return dex; }
		public function set dexterity(val:int):void
		{
			dex = val;
			dispatchChangeEvent(DEXTERITY);
		}
		
		[Bindable("abilityScoreChanged")]
		public function get constitution():int { return con; }
		public function set constitution(val:int):void
		{
			con = val;
			dispatchChangeEvent(CONSTITUTION);
		}
		
		[Bindable("abilityScoreChanged")]
		public function get intelligence():int { return itl; }
		public function set intelligence(val:int):void
		{
			itl = val;
			dispatchChangeEvent(INTELLIGENCE);
		}
		
		[Bindable("abilityScoreChanged")]
		public function get wisdom():int { return wis; }
		public function set wisdom(val:int):void
		{
			wis = val;
			dispatchChangeEvent(WISDOM);
		}
		
		[Bindable("abilityScoreChanged")]
		public function get charisma():int { return cha; }
		public function set charisma(val:int):void
		{
			cha = val;
			dispatchChangeEvent(CHARISMA);
		}
		
		protected var defaultAbilityModifiers:Array = 
		[
			-5, -4, -4, -3, -3,
			-2, -2, -1, -1, 0,
			0, 1, 1, 2, 2,
			3, 3, 4, 4, 5,
			5, 6, 6, 7, 7,
			8, 8, 9, 9, 10,
			11, 11, 12, 12, 13,
			13, 14, 14, 15, 15
		];
		
										 
		protected var str:int = 0;
		protected var dex:int = 0;
		protected var con:int = 0;
		protected var itl:int = 0;
		protected var wis:int = 0;
		protected var cha:int = 0;
		
		protected var modifiers:ArrayCollection;
		protected var currentFilterType:uint = 0;
		
		
		
		public function AbilityScores(str:Number=0, 
								 dex:Number=0, 
								 con:Number=0, 
								 int:Number=0, 
								 wis:Number=0, 
								 cha:Number=0):void
		{
			this.str				= str;
			this.dex				= dex;
			this.con				= con;
			this.itl				= itl;
			this.wis				= wis;
			this.cha				= cha;
			
			modifiers 				= new ArrayCollection();
		}
		
		/*
		public function getAbilityBonus(ability:uint):int
		{
			var val:int = 0;
			switch(ability)
			{
				case STRENGTH:			val = mod_array[strength];
				
				case DEXTERITY:			val = mod_array[dexterity];
				
				case CONSTITUTION:		val = mod_array[constitution];
				
				case INTELLIGENCE:		val = mod_array[intelligence];
				
				case WISDOM:			val = mod_array[wisdom];
				
				case CHARISMA:			val = mod_array[charisma];
			}
			return val;
		}
		
		public function addModifier(ability:Number, 
									name:String, 
									type:String, 
									adjustment:Number):Modifier
		{
			var o:Modifier = new Modifier(name, type, adjustment);
			modifier_obj[ability].push(o);
			return o;
		}
		*/
		
		public function getAbility(ability:uint):int
		{
			var value:int = 0;
			switch(ability)
			{
				case STRENGTH:
					value += getAppliedModifiers(STRENGTH);
					break;
				
				case DEXTERITY:
					value += getAppliedModifiers(DEXTERITY);
					break;
				
				case CONSTITUTION:
					value += getAppliedModifiers(CONSTITUTION);
					break;
				
				case INTELLIGENCE:
					value += getAppliedModifiers(INTELLIGENCE);
					break;
				
				case WISDOM:
					value += getAppliedModifiers(WISDOM);
					break;
				
				case CHARISMA:
					value += getAppliedModifiers(CHARISMA);
					break;
			}
			return value;
		}
		
		public function getAbilityModifier(ability:uint):int
		{
			switch(ability)
			{
				case STRENGTH:
					return defaultAbilityModifiers[str];
				
				case DEXTERITY:
					return defaultAbilityModifiers[dex];
				
				case CONSTITUTION:
					return defaultAbilityModifiers[con];
				
				case INTELLIGENCE:
					return defaultAbilityModifiers[itl];
				
				case WISDOM:
					return defaultAbilityModifiers[wis];
				
				case CHARISMA:
					return defaultAbilityModifiers[cha];
				
			}
			return 0; 
		}
		
		public function getAppliedModifiers(type:uint):int
		{
			currentFilterType = type;
			var mods:Array = modifiers.source.filter(filterByAbilityType, this);
			var value:int = 0;
			var len:int = mods.length;
			var modifier:Modifier;
			for(var index:uint = 0; index < len; index++)
			{
				modifier = modifiers.getItemAt(index) as Modifier;
				value += modifier.adjustment;
			}
			return value;
		}
		
		public function filterByAbilityType(item:*):Boolean
		{
			if(item is Modifier)
			{
				if(Modifier(item).attribute == currentFilterType)
				{
					return true;
				}
				else
				{
					return false;
				}
			}
			else
			{
				return false;
			}
		}
		
		
		protected function dispatchChangeEvent(type:uint):void
		{
			var evt:DnDEvent = new DnDEvent(DnDEvent.ABILITY_SCORE_CHANGED);
			evt.abilityScoreType = type;
			dispatchEvent(evt);
		}
		
		public function toXML():XML
		{
			var asXML:XML = 
				<abilityscores>
					<strength>{strength}</strength>
					<dexterity>{dexterity}</dexterity>
					<constitution>{constitution}</constitution>
					<intelligence>{intelligence}</intelligence>
					<wisdom>{wisdom}</wisdom>
					<charisma>{charisma}</charisma>
				</abilityscores>;
			return asXML;
		}
		
		public function buildFromXML(xml:XML):void
		{
			
			strength 					= parseInt(xml.abilityscores.strength);
			dexterity 					= parseInt(xml.abilityscores.dexterity);
			constitution 				= parseInt(xml.abilityscores.constitution);
			intelligence 				= parseInt(xml.abilityscores.intelligence);
			wisdom 						= parseInt(xml.abilityscores.wisdom);
			charisma 					= parseInt(xml.abilityscores.charisma);
		}
		
		public function addModifier(modifier:Modifier):void
		{
			modifiers.addItem(modifier);
		}
		
		public function removeModifier(modifier:Modifier):void
		{
			modifiers.removeItemAt(modifiers.getItemIndex(modifier));
			//throw new Error("Modifier not found for ID: " + modifierID);
		}

	}

}































